#include "dbkeepalive.h"
#include <iostream>

using namespace com_oocl_monitor::service;

DbKeepAlive::DbKeepAlive(OcciPool *pool)
	:_pool(pool) {
}
void DbKeepAlive::run() {
	HANDLE coutMutex = OpenMutex(MUTEX_ALL_ACCESS, false, TEXT("coutMutex"));
	WaitForSingleObject(coutMutex, INFINITE);
	std::cout << "Test db connectiveness!" << std::endl;
	ReleaseMutex(coutMutex);
	Connection *con = nullptr;
	Statement *stmt = nullptr;
	ResultSet *rs = nullptr;
	try {
		con = _pool->getConnection();
		stmt = con->createStatement("select sysdate from dual");
		rs = stmt->executeQuery();
	}
	catch (const SQLException &e) {
		WaitForSingleObject(coutMutex, INFINITE);
		std::cout << "DB Pool is Dead!" << std::endl;
		ReleaseMutex(coutMutex);
		string constr = _pool->Constr();
		string usr = _pool->Usr();
		string pwd = _pool->Pwd();
		if (con == nullptr) {
			delete(_pool);
		}
		else if (stmt == nullptr) {
			_pool->releaseConnection(con);
			delete(_pool);
		}
		else {
			con->terminateStatement(stmt);
			_pool->releaseConnection(con);
			delete(_pool);
		}

		WaitForSingleObject(coutMutex, INFINITE);
		std::cout << "Try to re-create DB Pool." << std::endl;
		ReleaseMutex(coutMutex);
		_pool = new OcciPool(constr, usr, pwd);
		WaitForSingleObject(coutMutex, INFINITE);
		std::cout << "Re-create DB Pool succeed!\n" << std::endl;
		ReleaseMutex(coutMutex);
		CloseHandle(coutMutex);
		return;
	}
	stmt->closeResultSet(rs);
	con->terminateStatement(stmt);
	_pool->releaseConnection(con);
	WaitForSingleObject(coutMutex, INFINITE);
	std::cout << "Db Pool is alive!\n" << std::endl;
	ReleaseMutex(coutMutex);
	CloseHandle(coutMutex);
}
